import React from "react";
import {
	Tree,
	Form,
	Input,
	Radio,
	Switch,
	Button,
	Select,
	Checkbox,
	DatePicker,
	TreeSelect,
	TimePicker,
	Typography,
	InputNumber
} from "antd";
import { DownloadOutlined, LockOutlined } from "@ant-design/icons";

import {
	ResourceTreeSelect,
	IUploadItem,
	// BizSelect,
	// CitySelect,
	// TownSelect,
	RoleSelect,
	// EntitySelect,
	// AreaTreeSelect,
	// DistrictSelect,
	RoleTypeSelect
	// EntityTreeSelect,
	// SearchSelect,
	// RegionTreeSelect,
} from "@/components";
import { trimFormInput } from "@/utils/util";
import request from '@/utils/request'

import type {
	TreeConfig,
	UploadConfig,
	InputConfig,
	SelectConfig,
	SwitchConfig,
	TextareaConfig,
	CheckboxConfig,
	DownLoadConfig,
	FormItemConfig,
	DatePickerConfig,
	TimePickerConfig,
	TreeSelectConfig,
	RadioGroupConfig,
	InputNumberConfig,
	InputPasswordConfig,
	CheckboxGroupConfig,
	DateRangePickerConfig,
	TimeRangePickerConfig
} from "./type";

export type { FormItemConfig };

const { Text } = Typography

export const InputItem = (props: InputConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item getValueFromEvent={trimFormInput} {...formItemProps}>
			<Input allowClear placeholder="请输入" {...childProps} />
		</Form.Item>
	);
};

export const TextAreaItem = (props: TextareaConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item getValueFromEvent={trimFormInput} {...formItemProps}>
			<Input.TextArea allowClear placeholder="请输入" autoSize={{ minRows: 2 }} {...childProps} />
		</Form.Item>
	);
};

export const InputNumberItem = (props: InputNumberConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<InputNumber {...childProps}></InputNumber>
		</Form.Item>
	);
};

export const InputPasswordItem = (props: InputPasswordConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<Input.Password
				type="password"
				prefix={<LockOutlined className="dark03" />}
				placeholder="8-16个字符，需包含字母、数字及字符"
				{...childProps}
			/>
		</Form.Item>
	);
};

export const DatePickerItem = (props: DatePickerConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			{/*  @ts-ignore */}
			<DatePicker allowClear showTime {...childProps} />
		</Form.Item>
	);
};

export const DateRangePickerItem = (props: DateRangePickerConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<DatePicker.RangePicker
				// @ts-ignore
				showTime
				allowClear
				format="YYYY-MM-DD HH:mm:ss"
				{...childProps}
			></DatePicker.RangePicker>
		</Form.Item>
	);
};

export const TimePickerItem = (props: TimePickerConfig) => {
	const { formItemProps = {}, childProps } = props;
	return (
		<Form.Item {...formItemProps}>
			<TimePicker allowClear {...childProps} />
		</Form.Item>
	);
};

export const TimeRangePickerItem = (props: TimeRangePickerConfig) => {
	const { formItemProps = {}, childProps } = props;
	return (
		<Form.Item {...formItemProps}>
			<TimePicker.RangePicker allowClear {...childProps}></TimePicker.RangePicker>
		</Form.Item>
	);
};

export const DownLoadItem = (props: DownLoadConfig) => {
	const { formItemProps = {}, childProps } = props;
	const { action, data, linkName = "path", beforeDownload } = childProps;
	const download = () => {
		if (typeof beforeDownload === "function" && !beforeDownload()) {
			return;
		}
		request(action, { data }).then(res => {
		  if (res.code === 0) {
		    window.open(typeof res.data === 'string' ? res.data : res.data?.[linkName])
		  }
		})
	};
	return (
		<Form.Item {...formItemProps}>
			<Button icon={<DownloadOutlined />} onClick={download}>
				下载模版
			</Button>
		</Form.Item>
	);
};

export const UploadItem = (props: UploadConfig) => {
	const { formItemProps = {}, children } = props;
	return children ? (
		<Form.Item label="上传文件" {...formItemProps}>
			{renderFormItemComponents(children)}
		</Form.Item>
	) : (
		<IUploadItem {...props}></IUploadItem>
	);
};

export const SelectItem = (props: SelectConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<Select allowClear showSearch placeholder="请选择" optionFilterProp="label" {...childProps}></Select>
		</Form.Item>
	);
};

export const TreeSelectItem = (props: TreeSelectConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<TreeSelect showSearch allowClear placeholder="请选择" treeDefaultExpandAll={false} {...childProps} />
		</Form.Item>
	);
};

export const TreeItem = (props: TreeConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<Tree checkable blockNode {...childProps} />
		</Form.Item>
	);
};

export const RadioGroupItem = (props: RadioGroupConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<Radio.Group {...childProps}></Radio.Group>
		</Form.Item>
	);
};

export const CheckboxItem = (props: CheckboxConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps} valuePropName="checked">
			<Checkbox {...childProps}>{childProps.children}</Checkbox>
		</Form.Item>
	);
};

export const CheckboxGroupItem = (props: CheckboxGroupConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps}>
			<Checkbox.Group {...childProps} />
		</Form.Item>
	);
};

export const SwitchItem = (props: SwitchConfig) => {
	const { formItemProps = {}, childProps = {} } = props;
	return (
		<Form.Item {...formItemProps} valuePropName="checked">
			<Switch {...childProps} />
		</Form.Item>
	);
};

const wapperConfig = (config: FormItemConfig) => {
	const formItemProps = config?.formItemProps || {};
	const { label } = formItemProps;
	if (typeof label === "string") {
		// formItemProps.label = <Text ellipsis={{ tooltip: label }}>{label}</Text>
	}
	return config;
};

export const renderFormItemComponents = (
	formItemsConfig: FormItemConfig[],
	cb?: (component: React.ReactElement, idx: number) => React.ReactElement
) => {
	const componentMap = {
		input: InputItem,
		textArea: TextAreaItem,
		inputPassword: InputPasswordItem,
		select: SelectItem,
		// bizSelect: BizSelect,
		// citySelect: CitySelect,
		// districtSelect: DistrictSelect,
		// townSelect: TownSelect,
		// entitySelect: EntitySelect,
		roleSelect: RoleSelect,
		roleTypeSelect: RoleTypeSelect,
		treeSelect: TreeSelectItem,
		// regionTreeSelect: RegionTreeSelect,
		// entityTreeSelect: EntityTreeSelect,
		// areaTreeSelect: AreaTreeSelect,
		resourceTreeSelect: ResourceTreeSelect,
		datePicker: DatePickerItem,
		dateRangePicker: DateRangePickerItem,
		timePicker: TimePickerItem,
		timeRangePicker: TimeRangePickerItem,
		radioGroup: RadioGroupItem,
		inputNumber: InputNumberItem,
		upload: UploadItem,
		download: DownLoadItem,
		checkboxGroup: CheckboxGroupItem,
		checkbox: CheckboxItem,
		tree: TreeItem,
		// searchSelect: SearchSelect,
		switch: SwitchItem
	};
	return formItemsConfig
		?.map((item, idx) => {
			if (!item) {
				return item;
			}
			const key = item.type ? item.type + idx : idx;
			if (item.itemRender && typeof item.itemRender === "function") {
				return <React.Fragment key={key}>{(item.itemRender as any)()}</React.Fragment>;
			}
			const Component = componentMap[item.type as keyof typeof componentMap];
			if (Component) {
				const config = wapperConfig(item);
				// @ts-ignore
				return <Component {...config} key={key}></Component>;
			}
			return null;
		})
		.map((component, idx) => (cb && component ? cb(component, idx) : component));
};
